package cn.com.pansky.util;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

public class CommonUtils {

	public final static String dateStyleStr = "yyyy-MM-dd";
	public final static String ymStyleStr = "yyyyMM";

	/**
	 * 获得人员的出生日期
	 * 
	 * @param psidcd
	 *            身份证号
	 * @return String
	 */
	public static String getBirthDay(String psidcd) {
		String birthDay = "";
		// 如果不是有效的18位或15位个人身份证号码
		if (!isIdentityId(psidcd)) {
			return "";
		}
		// 修补15位个人身份证号码为18位
		if (psidcd.length() == 15) {
			psidcd = fixPersonIDCode(psidcd);
		}

		birthDay = psidcd.substring(6, 14);
		// 判断是否正确的日期格式：yyyyMMdd
		if (!isDate(birthDay)) {
			return "";
		}
		 birthDay = birthDay.substring(0, 4) + "-" + birthDay.substring(4, 6)
		 + "-" +
		 birthDay.substring(6, 8);

		return birthDay;
	}

	/**
	 * 取应用服务器当前日期（应用服务器） 日期的格式："yyyyMMdd"
	 * 
	 * @return String
	 */
	public static String get8BitCurTimeAPP() {
		String timeFormat = "yyyyMMdd";
		return date2Str(new Date(), timeFormat);
	}

	/**
	 * 把时间转换为字串
	 * 
	 * @param date
	 *            待转换的时间
	 * @param format
	 *            转换格式：yyyyMMdd
	 * @return String
	 */
	public static String date2Str(Date date, String format) {
		if (isNull(date)) {
			return "";
		}

		String precision = "";
		if ("yyyyMMddHHmmss.SSSSSS".equalsIgnoreCase(format)) {
			precision = "000";
			format = "yyyyMMddHHmmss.SSSSSS";
		}
		if (dateStyleStr.equalsIgnoreCase(format)) {
			format = dateStyleStr;
		}
		format = isEmpty(format) ? dateStyleStr : format;
		format = "yyyyMMddHHmmss.SSSSSS".equalsIgnoreCase(format) ? "yyyyMMddHHmmss.SSS"
				: format;
		// SimpleDateFormat的转换毫秒的精度最多为3位
		SimpleDateFormat df = new SimpleDateFormat(format);

		return df.format(date) + precision;
	}

	/**
	 * 获得串s的字节长度
	 * 
	 * @param src
	 *            串s
	 * @return int 字节长度
	 */
	public static int getByteSize(String src) {
		int ret = 0;
		if (isNull(src)) {
			return ret;
		}
		try {
			ret = getBytes_encode(src).length;
		} catch (Exception e) {
		}
		return ret;
	}

	public static byte[] getBytes_encode(String sourceStr) {
		byte[] newByte = null;
		try {
			newByte = sourceStr.getBytes("GBK");
			throw new Exception();
		} catch (Exception e) {
			// cat.debug("getBytes_encode(GBK) Error, source String is:" +
			// sourceStr);
			newByte = sourceStr.getBytes();
		}
		return newByte;
	}

	/**
	 * 格式化数字
	 * 
	 * @param number
	 *            原数字
	 * @param patternSize
	 *            小数位的长度
	 * @return String
	 */
	public static String format(String number, int patternSize) {
		double d = toDouble(number);
		String pattern = patternSize < 1 ? "0" : fixSuffixStr("0.",
				patternSize + 2, "0");
		return format(d, pattern);
	}

	public static String format(double number, int patternSize) {
		String pattern = patternSize < 1 ? "0" : fixSuffixStr("0.",
				patternSize + 2, "0");
		return format(number, pattern);
	}

	/**
	 * 格式化数字（不推荐使用）
	 * 
	 * @param number
	 *            原double
	 * @param pattern
	 *            输出数字字串的格式（eg:"0.00"）
	 * @return String 转为子串
	 */
	public static String format(double number, String pattern) {
		DecimalFormat df = new DecimalFormat(pattern);
		return df.format(number);
	}

	/**
	 * 给字串加上后缀（按字符）
	 * 
	 * @param srcStr
	 *            需要加入后缀的字串
	 * @param length
	 *            返回字串总长度
	 * @param fixChar
	 *            后缀字符
	 * @return String 加上后缀后的字串
	 */
	public static String fixSuffixStr(String srcStr, int length, String fixChar) {
		if (isNull(srcStr)) {
			srcStr = "";
		}
		StringBuffer sb = new StringBuffer(length);
		for (int i = 0; i < length - srcStr.length(); i++) {
			sb.append(fixChar);
		}
		return srcStr + new String(sb);
	}

	/**
	 * Convert a String to Double.
	 * 
	 * @param sValue
	 *            数字串
	 * @return int
	 */
	public static double toDouble(String sValue) {
		try {
			return Double.parseDouble(sValue);
		} catch (Exception e) {
			// cat.debug("Convert  [" + sValue + "] to double Failed!") ;
			// e.printStackTrace();
			return 0.0;
		}
	}

	/**
	 * Convert a String to Int.
	 * 
	 * @param sValue
	 *            数字串
	 * @return int
	 */
	public static int toInt(String sValue) {
		try {
			sValue = format(sValue, 0);
			return Integer.parseInt(sValue);
		} catch (Exception e) {
			// cat.debug("Convert  [" + sValue + "] to Int Failed!");
			e.printStackTrace();
			return 0;
		}
	}

	/**
	 * 判断是否正确的日期格式
	 * 
	 * @param sValue
	 *            日期字串：yyyyMMdd
	 * @return boolean
	 */
	public static boolean isDate1(String sValue) {
		if (isEmpty(sValue)) {
			return false;
		}
		int intYear;
		int intMon;
		int intDay;
		boolean boolLeapYear = false;
		if (getByteSize(sValue) != 8) {
			// 长度只能为8位
			return false;
		}
		intYear = toInt(sValue.substring(0, 4));
		intMon = toInt(sValue.substring(4, 6));
		intDay = toInt(sValue.substring(6, 8));
		if (intMon > 12 || intMon < 1) {
			return false;
		}
		if (intYear < 1800) {
			return false;
		}
		if ((intMon == 1 || intMon == 3 || intMon == 5 || intMon == 7
				|| intMon == 8 || intMon == 10 || intMon == 12)
				&& (intDay > 31 || intDay < 1)) {
			return false;
		}
		if ((intMon == 4 || intMon == 6 || intMon == 9 || intMon == 11)
				&& (intDay > 30 || intDay < 1)) {
			return false;
		}
		if (intMon == 2) {
			if ((intYear % 100) == 0) {
				if ((intYear % 400) == 0) {
					boolLeapYear = true;
				}
			} else {
				if ((intYear % 4) == 0) {
					boolLeapYear = true;
				}
			}
			if (boolLeapYear) {
				if (intDay > 29 || intDay < 1) {
					return false;
				}
			} else {
				if (intDay > 28 || intDay < 1) {
					return false;
				}
			}
		}
		return true;
	}

	/**
	 * 判断Object是否为null
	 * 
	 * @param oValue
	 *            对象
	 * @return boolean
	 */
	public static boolean isNull(Object oValue) {
		return oValue == null ? true : false;
	}

	/**
	 * 判断字符串是否为空串""
	 * 
	 * @param sValue
	 *            字符串
	 * @return boolean
	 */
	public static boolean isEmpty(String sValue) {
		if (isNull(sValue)) {
			return true;
		}
		return sValue.trim().equals("") ? true : false;
	}

	/**
	 * 判断是否正确的日期格式：现在
	 * 
	 * @param sValue
	 *            日期字串：yyyy-MM-dd
	 * @return boolean
	 */
	public static boolean isDate2(String sValue) {
		if (isEmpty(sValue)) {
			return false;
		}
		if (sValue.length() != 10) {
			return false;
		}
		String temp1 = sValue.substring(0, 4);
		String temp2 = sValue.substring(5, 7);
		String temp3 = sValue.substring(8, 10);
		String seperator1 = sValue.substring(4, 5);
		String seperator2 = sValue.substring(7, 8);
		sValue = temp1 + temp2 + temp3;
		if (!(seperator1.equals("-") && seperator2.equals("-"))) {
			return false;
		}

		return isDate1(sValue);
	}

	/**
	 * 判断是否正确的日期格式
	 * 
	 * @param sValue
	 *            日期字串：yyyyMMdd 或 yyyy-MM-dd
	 * @return boolean
	 */
	public static boolean isDate(String sValue) {
		if (sValue.length() == 10) {
			return isDate2(sValue);
		} else if (sValue.length() == 8) {
			return isDate1(sValue);

		} else {
			return false;
		}
	}

	/**
	 * 判断是否是有效的18位或15位个人身份证号码
	 * 
	 * @param identityId
	 *            18位或15位个人身份证号码
	 * @return boolean
	 */
	public static boolean isIdentityId(String identityId) {
		if (isEmpty(identityId)) {
			return false;
		}
		try {
			if (identityId.length() == 18) {
				// String identityId15 = identityId.substring(0, 6)
				// +identityId.substring(8, 17);
				// cat.debug("the identityId15 is : "+identityId15);
				if (fixPersonIDCode(identityId).equalsIgnoreCase(identityId)) {
					return true;
				} else {
					return false;
				}
			} else if (identityId.length() == 15) {
				try {
					if (isLong(identityId)) {
						String identityId15 = "19"
								+ identityId.substring(6, 12);
						// 判断所得到的出身是不是正确的日期格式
						if (isDate(identityId15)) {
							return true;
						} else {
							return false;
						}
					} else {
						return false;
					}
				} catch (Exception ex) {
					return false;
				}
			} else {
				return false;
			}
		} catch (Exception ex) {
			return false;
		}
	}

	/**
	 * 判断是否为长整数
	 * 
	 * @param sValue
	 *            数字串
	 * @return boolean
	 */
	public static boolean isLong(String sValue) {
		if (isEmpty(sValue)) {
			return false;
		}
		try {
			Long.parseLong(sValue);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	/**
	 * 修补15,17位个人身份证号码为18位
	 * 
	 * @param personIDCode
	 *            15,17位身份证
	 * @return String 18位身份证
	 */
	public static String fixPersonIDCode(String personIDCode) {

		String id17 = "";
		if (personIDCode.trim().length() != 18
				&& personIDCode.trim().length() != 17
				&& personIDCode.trim().length() != 15) {
			return personIDCode;
		}
		/**
		 * 2014-10-17增加对18位身份证校验处理。by suxh
		 * */
		if (personIDCode.trim().length() == 18) {
			String yearFront2 = personIDCode.substring(6, 8);// 年份前两位
			personIDCode = personIDCode.substring(0, 6)
					+ personIDCode.substring(8, 17);
			id17 = personIDCode.substring(0, 6) + yearFront2
					+ personIDCode.substring(6, 15); // 15为身份证补'19'
		} else if (personIDCode.trim().length() == 15) {
			id17 = personIDCode.substring(0, 6) + "19"
					+ personIDCode.substring(6, 15); // 15为身份证补'19'
		} else {
			id17 = personIDCode;
		}
		if (id17.indexOf("A") > 0 || id17.indexOf("X") > 0
				|| id17.indexOf("x") > 0) {
			return personIDCode;
		}
		char[] code = { '1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2' }; // 11个
		int[] factor = { 0, 2, 4, 8, 5, 10, 9, 7, 3, 6, 1, 2, 4, 8, 5, 10, 9, 7 }; // 18个;
		int[] idcd = new int[18];
		int i;
		int j;
		int sum;
		int remainder;

		for (i = 1; i < 18; i++) {
			j = 17 - i;
			idcd[i] = Integer.parseInt(id17.substring(j, j + 1));
		}

		sum = 0;
		for (i = 1; i < 18; i++) {
			sum = sum + idcd[i] * factor[i];
		}
		remainder = sum % 11;
		String lastCheckBit = String.valueOf(code[remainder]);
		return id17 + lastCheckBit;

	}

	/**
	 * 获得人员在某一年的年龄
	 * 
	 * @param psidcd
	 *            身份证号
	 * @param yearMonth
	 *            计算年龄的年月
	 * @return int 年龄
	 */
	public static int countPersonAge(String psidcd, String yearMonth) {
		// if (SysConstant.PersonIdencod_DefaultIdencod.equals(psidcd)){ //
		// 没有身份证???
		// return 0 ;
		// }
		if (psidcd.trim().length() < 18) { // 身份证位数不对
			return 0;
		}
		String birthYM = psidcd.substring(6, 12);
		return countAge(birthYM, yearMonth);
	}

	/**
	 * 获得人员在某一年的年龄
	 * 
	 * @param birthday
	 *            出生日期 yyyyMMdd
	 * @param yearMonth
	 *            计算年龄的年月
	 * @return int 年龄
	 */
	public static int countPersonAgeByBirthday(String birthday, String yearMonth) {
		if (!isDate(birthday)) {
			return 0;
		}
		String birthYM = birthday.substring(0, 4) + birthday.substring(5, 7);
		return countAge(birthYM, yearMonth);
	}

	/**
	 * 获得人员在某一年的年龄
	 * 
	 * @param birthYM
	 *            出生年月
	 * @param yearMonth
	 *            计算年龄的年月
	 * @return int 年龄
	 */
	public static int countAge(String birthYM, String yearMonth) {
		if (!isYearMonth(birthYM)) {
			return 0;
		}
		if (!isYearMonth(yearMonth)) {
			return 0;
		}
		int age = 0;
		age = (monthsBetweenYM(birthYM, yearMonth)) / 12;
		return age;
	}

	/**
	 * 计算两个年月间的月数--同月返回为0
	 * 
	 * @param begYM
	 *            开始年月（前）YYYYMM
	 * @param endYM
	 *            结束年月（后）YYYYMM
	 * @return int
	 */
	public static int monthsBetweenYM(String begYM, String endYM) {
		if (!isYearMonth(begYM)) {
			begYM = date2Str(str2Date("1900-01-01", dateStyleStr), ymStyleStr);
		}
		if (!isYearMonth(endYM)) {
			endYM = date2Str(str2Date("1900-01-01", dateStyleStr), ymStyleStr);
		}

		int months = 0;
		try {
			int begYear = new Integer(begYM.substring(0, 4)).intValue();
			int endYear = new Integer(endYM.substring(0, 4)).intValue();
			int begMonth = new Integer(begYM.substring(4, 6)).intValue();
			int endMonth = new Integer(endYM.substring(4, 6)).intValue();
			months = (endYear - begYear) * 12 + (endMonth - begMonth);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return months;
	}

	/**
	 * 把字串转换为日期
	 * 
	 * @param sdate
	 *            字串形式的日期（最长的格式：yyyyMMddHHmmss.SSS）
	 * @param format
	 *            字串格式
	 * @return Date 转换为日期类型
	 */
	public static java.util.Date str2Date(String sdate, String format) {
		if (isEmpty(sdate)) {
			return null;
		}
		SimpleDateFormat df = new SimpleDateFormat(format);
		Date new_date = null;
		try {
			new_date = df.parse(sdate);
		} catch (Exception e) {
			e.printStackTrace();
			// cat.debug("把字串转换为日期错误：" + sdate + "，需转换的日期格式为：" + format);
		}
		return new_date;
	}

	/**
	 * 判断是否正确的年月格式
	 * 
	 * @param sValue
	 *            日期字串：yyyyMM
	 * @return boolean
	 */
	public static boolean isYearMonth(String sValue) {
		if (isEmpty(sValue)) {
			return false;
		}
		if (sValue.length() != 6) {
			return false;
		}
		String temp1 = sValue.substring(0, 4);
		String temp2 = sValue.substring(4);
		sValue = temp1 + temp2 + "01";
		return isDate(sValue);
	}
}
